package demoMod.invincibleOne.ui;

import basemod.BaseMod;
import basemod.abstracts.CustomSavable;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.google.gson.reflect.TypeToken;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.helpers.MathHelper;
import com.megacrit.cardcrawl.rewards.RewardItem;
import demoMod.invincibleOne.characters.InvincibleOne;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class BingoRewardList implements CustomSavable<List<RewardItem.RewardType>> {
    private final List<BingoRewardItem> rewards = new ArrayList<>();

    public boolean hide = true;

    public float alpha = 1.0F;

    private float rewardSpacing = 100.0F;

    public boolean claimingReward;

    public BingoRewardList() {
        BaseMod.addSaveField("BingoRewardList", this);
    }

    public void update() {
        if (!(AbstractDungeon.player instanceof InvincibleOne)) {
            return;
        }
        float targetAlpha;
        float targetRewardSpacing;
        if (hide) {
            targetRewardSpacing = 0.0F;
            targetAlpha = 0.0F;
        } else {
            targetRewardSpacing = 100.0F;
            targetAlpha = 1.0F;
        }
        rewardSpacing = MathHelper.orbLerpSnap(rewardSpacing, targetRewardSpacing);
        alpha = MathHelper.orbLerpSnap(alpha, targetAlpha);
        float startY = Settings.HEIGHT - 102.0F * Settings.scale;
        for (RewardItem reward : rewards) {
            startY -= rewardSpacing * Settings.yScale;
            reward.move(startY);
        }
        rewards.forEach(RewardItem::update);
    }

    public void render(SpriteBatch sb) {
        if (!(AbstractDungeon.player instanceof InvincibleOne)) {
            return;
        }
        rewards.forEach(reward -> reward.render(sb));
    }

    public List<BingoRewardItem> getRewards() {
        return rewards;
    }

    @Override
    public List<RewardItem.RewardType> onSave() {
        return rewards.stream().map(reward -> reward.type).collect(Collectors.toList());
    }

    @Override
    public void onLoad(List<RewardItem.RewardType> data) {
        if (data != null) {
            rewards.clear();
            BingoRewardItem.Builder cardRewardBuilder = new BingoRewardItem.Builder().setType(RewardItem.RewardType.CARD);
            BingoRewardItem.Builder cardRemovalRewardBuilder = new BingoRewardItem.Builder().setType(BingoRewardItem.BingoRewardType.INVINCIBLE_CARD_REMOVAL);
            BingoRewardItem.Builder legendaryCardRewardBuilder = new BingoRewardItem.Builder().setType(BingoRewardItem.BingoRewardType.LEGENDARY_CARD);
            Map<RewardItem.RewardType, BingoRewardItem.Builder> builderMap = new HashMap<>();
            builderMap.put(RewardItem.RewardType.CARD, cardRewardBuilder);
            builderMap.put(BingoRewardItem.BingoRewardType.INVINCIBLE_CARD_REMOVAL, cardRemovalRewardBuilder);
            builderMap.put(BingoRewardItem.BingoRewardType.LEGENDARY_CARD, legendaryCardRewardBuilder);
            for (RewardItem.RewardType type : data) {
                rewards.add(builderMap.getOrDefault(type, cardRewardBuilder).build());
            }
        }
    }

    @Override
    public Type savedType() {
        return new TypeToken<List<RewardItem.RewardType>>(){}.getType();
    }
}
